/**
 * (c) 2015-2020
 *
 * Author: zeyuphoenix
 *
 * License: www.blogjava.net/zeyuphoenix
 *
 * version: 1.0.0
 */

(function (root, factory) {

    "user strict";

    if (typeof define === 'function' && define.amd) {
        define(['jquery', 'echarts'], factory);
    } else {
        root.ChartData = factory($, echarts);
    }
}(this, function ($, echarts) {

    "user strict";

    /**
     * 常用的图的配置项
     */
    var defaultChartConst = {
        //图的默认高度
        DEFAULT_HEIGHT: 300
    };

    // 提供项目的默认配置项,保持风格统一,覆盖echarts的配置项
    // 其它配置或者扩充参考echarts文档
    var defaultSettings = {
        // 部分属性可能需要覆盖
        // 全图默认背景，默认为无(null，同'rgba(0,0,0,0)')，透明
        backgroundColor: null,
        // 数值系列的颜色列表，array数组,默认为null则采用内置颜色，可配数组，eg：['#87cefa', 'rgba(123,123,123,0.5)','...']，
        // 当系列数量个数比颜色列表长度大时将循环选取
        // 如果没有theme, 项目的图的统一颜色在这里指定
        color: null,
        //头信息
        title: {
            // 是否显示标题组件
            show: true,
            //主标题，'\n'指定换行
            text: '',
            //主标题链接
            link: '',
            //副标题
            subtext: '',
            //副标题链接
            sublink: ''
            //textStyle
            //subtextStyle
            // 其它属性因为一般都使用默认值,之后的类似,chart data也不提供,如果需要请使用options里的config覆盖
        },
        //工具箱
        toolbox: {
            // 显示策略，可选为：true（显示） | false（隐藏）
            show: true,
            // 布局方式，默认为水平布局，可选为：'horizontal' | 'vertical'
            orient: 'horizontal',
            // 水平安放位置，默认为全图居右，可选为：'center' | 'left' | 'right' | {number}（x坐标，单位px）
            left: 'right',
            //垂直安放位置，默认为全图顶端，可选为：'top' | 'bottom' | 'center' | {number}（y坐标，单位px）
            top: 'top',
            // 工具箱icon大小，单位（px）
            itemSize: 16,
            // 在dashboard显示小的图的时候,需要把一些工具隐藏
            // TODO 以后多语言需要修改
            feature: {
                //框选区域缩放，自动与存在的dataZoom控件同步，2个图标，分别是启用，缩放后退
                dataZoom: {
                    show: false,
                    title: {
                        dataZoom: '区域缩放',
                        dataZoomReset: '区域缩放还原'
                    }
                },
                // 数据视图，1个图标，打开数据视图，可设置更多属性
                // {boolean=} readOnly 默认数据视图为只读，可指定readOnly为false打开编辑功能
                // {Function=} optionToContent 自主编排数据视图的显示内容
                // {Function=} contentToOption 当数据视图readOnly为false时，会出现刷新按钮，如果是自主编排的显示内容，如何翻转也请自理
                // {Array=} lang 数据视图上有三个话术，默认是['Data View', 'close', 'refresh']，如需改写，可自定义
                // TODO 需要扩展这里实现表和图的切换
                dataView: {
                    show: false,
                    title: '数据视图',
                    readOnly: false,
                    // 转换有问题，echarts内部已经把这个区域设置为textArea，设置和取得的都是它的value值，不可再进行div渲染了
//                    optionToContent: function (opts) {
//                        console.info(opts);
//                        return '<div><button>test click</button></div>>'
//                    },
//                    contentToOption: function (vals, opts) {
//                        console.info(vals);
//                        console.info(opts);
//                    },
                    lang: ['数据视图：', '关闭', '刷新']
                },
                //动态类型切换，支持直角系下的折线图、柱状图、堆积、平铺转换，最多4个图标，分别是切换折线图，切换柱形图，切换为堆积，切换为平铺
                //{Array} type ['line', 'bar', 'stack', 'tiled']
                magicType: {
                    show: true,
                    title: {
                        line: '折线图切换',
                        bar: '柱形图切换',
                        stack: '堆积切换',
                        tiled: '平铺切换'
                    },
                    type: ['line', 'bar']
                },
                //还原，复位原始图表
                restore: {
                    show: true,
                    title: '还原'
                },
                // 保存图片（IE8-不支持），可设置更多属性
                // {string=} type 默认保存图片类型为'png'，需改为'jpeg'
                // {string=} name 指定图片名称，如不指定，则用图表title标题，如无title标题则图片名称默认为“ECharts”
                // {string=} lang 非IE浏览器支持点击下载，有保存话术，默认是“点击保存”，可修改
                saveAsImage: {
                    show: true,
                    title: '保存为图片',
                    type: 'png',
                    lang: ['点击保存']
                }
            }
        },
        // 提示框，鼠标悬浮交互时的信息提示
        tooltip: {
            // 显示策略，可选为：true（显示） | false（隐藏）
            show: true,
            // 'item' 数据项图形触发，主要在散点图，饼图等无类目轴的图表中使用。
            // 'axis' 坐标轴触发，主要在柱状图，折线图等会使用类目轴的图表中使用
            trigger: 'axis',   //触发类型，默认数据触发，可选为：'item' | 'axis'
            // 鼠标是否可进入提示框浮层中，默认为false，如需详情内交互，如添加链接，按钮，可设置为 true
            enterable: false,
            // 将来可能需要统一的tooltip效果
            // 内容格式器：{string}（Template） | {Function}，支持异步回调
            formatter: null,
            // 文本样式，默认为白色字体（详见textStyle）
            textStyle: {color: '#fff'}
        },
        // 图例,每个图表最多仅有一个图例,，混搭图表共享
        legend: {
            // 布局方式，默认为水平布局，可选为：'horizontal' | 'vertical'
            // 饼图需要使用 'vertical'
            orient: 'horizontal',
            // 水平安放位置，默认为全图居中，可选为：'center' | 'left' | 'right' | 20% |{number}（x坐标，单位px）
            // 饼图使用right
            left: 'center',
            // 垂直安放位置，默认为全图顶端，可选为：'top' | 'bottom' | 'middle' | 20% |{number}（y坐标，单位px）
            // 饼图需要考虑工具栏的高度,需要使用 40(数值型)
            top: 'top',
            // 默认只设定了图例文字颜色（详见textStyle） ，更个性化的是，要指定文字颜色跟随图例，可设color为'auto'
            // textStyle
            // data属性 是图例内容数组，数组项为{string}，每一项代表一个系列的name。
            // 使用根据该值索引series中同名系列所用的图表类型和itemStyle，如果索引不到，该item将默认为没启用状态
            // 如需个性化图例文字样式，可把数组项改为{Object}，知道文本样式和个性化图例icon，格式为
            //  {
            //      name : {string},
            //      textStyle : {Object},
            //      icon: {string}
            //  }
            data: []
        },
        // 与toolbox.feature.dataZoom同步
        // 数据区域缩放,数据展现范围选择
        // PS: 仅对直角坐标系图表有效
        // 数据大时可能会使用
        dataZoom: [
            {
                // 内置型数据区域缩放组件
                type: 'inside',
                // 布局方式，默认为水平布局，可选为：'horizontal' | 'vertical'
                orient: 'horizontal',
                // 数据缩放，选择起始比例，默认为0（%），从首个数据起选择。
                start: 0,
                // 数据缩放，选择结束比例，默认为100（%），到最后一个数据选择结束。
                end: 100
            },
            {
                // 滑动条型数据区域缩放组件
                type: 'slider',
                // 是否显示 组件。如果设置为 false，不会显示，但是数据过滤的功能还存在
                show: false,
                // 布局方式，默认为水平布局，可选为：'horizontal' | 'vertical'
                orient: 'horizontal',
                // 缩放变化是否实时显示，建议性能较低的浏览器或数据量巨大时不启动实时效果。
                realtime: true,
                // 数据缩放，选择起始比例，默认为0（%），从首个数据起选择。
                start: 0,
                // 数据缩放，选择结束比例，默认为100（%），到最后一个数据选择结束。
                end: 100
            }
        ],
        // 直角坐标系内绘图网格
        // PS: 仅对直角坐标系图表有效 --> 折线图，柱状图，散点图（气泡图）
        // echarts留的各个边太宽,需要调整
        // dashboard需要更小的边
        grid: {
            // 是否显示直角坐标系网格
            show: false,
            // 直角坐标系内绘图网格离容器左侧的距离，数值单位px，支持百分比（字符串），如'50%'(显示区域纵向中心)
            // left 的值为'left', 'center', 'right'，组件会根据相应的位置自动对齐
            left: 45,
            // 直角坐标系内绘图网格离容器上侧的距离，数值单位px，支持百分比（字符串），如'50%'(显示区域横向中心)
            // top 的值为'top', 'middle', 'bottom'，组件会根据相应的位置自动对齐
            top: 35,
            // 直角坐标系内绘图网格离容器右侧的距离，数值单位px，支持百分比（字符串），如'50%'(显示区域横向中心)
            right: 25,
            // 直角坐标系内绘图网格离容器下侧的距离，数值单位px，支持百分比（字符串），如'50%'(显示区域纵向中心)
            bottom: 25,
            // 背景颜色，默认透明。
            backgroundColor: 'rgba(0,0,0,0)',
            // 边框线宽
            borderWidth: 1,
            // 边框颜色。
            borderColor: '#ccc'
        },
        // 直角坐标系中横轴数组，数组中每一项代表一条横轴坐标轴，标准（1.0）中规定最多同时存在2条横轴
        // 坐标轴有两种类型，类目型和数值型（区别详见axis），横轴通常为类目型，但条形图时则横轴为数值型，散点图时则横纵均为数值型
        // 类目型：需要指定类目列表，坐标轴内有且仅有这些指定类目坐标
        xAxis: [
            {
                // 'value' 数值轴，适用于连续数据。
                // 'category' 类目轴，适用于离散的类目数据，为该类型时必须通过 data 设置类目数据。
                // 'time' 时间轴，适用于连续的时序数据，与数值轴相比时间轴带有时间的格式化，在刻度计算上也有所不同，例如会根据跨度的范围来决定使用月，星期，日还是小时范围的刻度
                type: 'category',          //坐标轴类型，横轴默认为类目型'category'
                // 刻度只是作为分隔线，标签和数据点都会在两个刻度之间的带(band)中间
                boundaryGap: false,        //类目起始和结束两端空白策略，默认为true留空，false则顶头
                name: '',                 //坐标轴名称
                axisLabel: {               //坐标轴文本标签选项
                    show: true,
                    interval: 'auto',     //标签显示挑选间隔，默认为'auto'，可选为：'auto'（自动隐藏显示不下的） | 0（全部显示） | {number}（用户指定选择间隔）
                    rotate: 0,	          //标签旋转角度，默认为0，不旋转，正值为逆时针，负值为顺时针，可选为：-90 ~ 90
                    // 横坐标格式化显示，根据需要修改
                    //间隔名称格式器formatter：
                    //{string}，模板（Template），其变量为：
                    //   {value}: 内容或值
                    //   {Function}，传递参数同模板变量：
                    //   eg：function (value){return "星期" + "日一二三四五六".charAt(value);'}
                    formatter: null       //格式下坐标的函数
                },
                // 类目型坐标轴文本标签数组，指定label内容。 数组项通常为文本，'\n'指定换行
                // 类目列表，同时也是label内容(textStyle这里暂时不设置)
                data: []
            }
        ],
        // 直角坐标系中纵轴数组，数组中每一项代表一条纵轴坐标轴，标准（1.0）中规定最多同时存在2条纵轴
        // 坐标轴有两种类型，类目型和数值型（区别详见axis），纵轴通常为数值型，但条形图时则纵轴为类目型
        // 数值型：需要指定数值区间，坐标轴内包含数值区间内容全部坐标
        yAxis: [
            {
                // 'value' 数值轴，适用于连续数据。
                // 'category' 类目轴，适用于离散的类目数据，为该类型时必须通过 data 设置类目数据。
                // 'time' 时间轴，适用于连续的时序数据，与数值轴相比时间轴带有时间的格式化，在刻度计算上也有所不同，例如会根据跨度的范围来决定使用月，星期，日还是小时范围的刻度
                type: 'value',           // 坐标轴类型，纵轴默认为数值型'value'
                name: '',                // 坐标轴名称，默认为空
                boundaryGap: [0, 0.1],   // 数值轴两端空白策略，数组内数值代表百分比，[原始数据最小值与最终最小值之间的差额，原始数据最大值与最终最大值之间的差额]
                scale: false,            // 脱离0值比例，放大聚焦到最终_min，_max区间,只在数值轴中（type: 'value'）有效
                splitNumber: 5,          // 分割段数，默认为5,
                axisLabel: {             // 坐标轴文本标签选项
                    show: true,
                    rotate: 0,	          //标签旋转角度，默认为0，不旋转，正值为逆时针，负值为顺时针，可选为：-90 ~ 90
                    //纵坐标格式化显示，根据需要修改
                    //间隔名称格式器formatter：
                    //{string}，模板（Template），其变量为：
                    //   {value}: 内容或值
                    //   {Function}，传递参数同模板变量：
                    //   eg：function (value){return "星期" + "日一二三四五六".charAt(value);'}
                    formatter: null      //格式下坐标的函数
                }
            }
        ],
        //驱动图表生成的数据内容数组，数组中每一项为一个系列的选项及数据
        series: [
//            {
//                name: null,                 //系列名称，如启用legend，该值将被legend.data索引相关
//                type: 'line',               //图表类型，可选为： 'line'（折线图） | 'bar'（柱状图） | 'pie'（饼图） | 'radar'（雷达图）
//                itemStyle: {                //图形样式，可设置图表内图形的默认样式和强调样式
//                    //默认留空,在具体实现里作出
//                },
//                data: []                    // 系列中的数据内容数组。数组项通常为具体的数据项
//            }
        ]

    };

    /**
     * 主题样式
     */
    var theme = 'macarons';

    var defaultOptions = {
        //dom 节点
        databind: null,
        //remote 默认是远程模式
        remote: true,
        // 'line' 'bar' 'pie' ‘radar' 'gauge' 'scatter' 'other'(需要设置slefDefine,自己加载config和ajax)
        type: 'line',
        //数据请求url地址
        dataurl: '',
        //数据请求参数
        params: {},
        //本地模式才生效
        datas: null,
        // 横轴的名称，也对应表格的名称列(如时间、协议名等)
        // 不设置则显示统计项
        angle: "统计项",

        //图的标题和副标题
        tilte: '',
        subtitle: null,
        //是否堆积,主图\线图设置后成为堆积图
        stack: false,
        //是否是面积图,线图设置后成为面积图,使用默认填充
        area: false,
        //饼图和雷达图提示的标题名称
        name: '',
        //饼图和雷达图是否有特殊效果,中空、渲染等
        radius: false,
        //线图和柱图、雷达图必须设置 字符串数组,类似['上行流量','下行流量']
        legends: [],

        //不使用自定义格式化，使用共通格式化时，是按1024还是按1000进行格式化，默认是1000
        //flow or package(other)
        formatType: 'package',
        //横纵坐标、雷达、甘特图显示的格式化函数
        labelFormatter: null,
        //tooltip的格式化函数
        tooltipFormatter: null,
        //图表的双击事件，函数,参数为param
        /**
         *
         * function(param){
         *      //type = param.type
         *      //seriesIndex = param.seriesIndex
         *      //dataIndex = param.dataIndex
         *      console.log(param);
         * }
         * eg:
         * param结构:
         *      data: 53
         *      dataIndex: 14
         *      event: MouseEvent
         *      name: "2013-03-15 20:15:34"
         *      seriesIndex: 0
         *      seriesName: "上行流量"
         *      type: "dblclick"
         *      value: 53
         */
        dblclick: null,

        // 目前只是为了统一,只支持最基本的图,line、bar、pie、scatter、radar、gauge几种,如果需要其它图类,或者是复杂的图,比如 线图和饼图混合
        // 等,请将slefDefine设置为true, 注意:这个设置为true后,将不会自动为你请求数据,你需要自己发送ajax请求,按照echarts官网的例子,把
        // 值和配置依次设置到下面的config属性中
        slefDefine: false,
        // 额外接口,必须 和图的option保持一致
        config: {}
    };

    // 图表对象,图创建的唯一入口
    var ChartData = function (options) {
        this.options = $.extend(true, {}, defaultOptions, options);
        this.__init();
        if (this.options.slefDefine) {
            this.refresh();
        } else {
            this.request();
        }
    };

    //图表的配置
    //图的对象方法
    ChartData.prototype = {

        // 构造
        constructor: ChartData,

        // 获取默认的常量
        DEFAULT_CHART_CONST: function () {
            return defaultChartConst;
        },

        // 初始化
        __init: function () {

            // 取得默认配置
            // 图表的配置
            this.options.chartConfig = this.getDefaultChartConfig(this.options.type);
            //设置标题
            if (this.options.tilte != null) {
                this.options.chartConfig.title.text = this.options.title;
            }
            //设置副标题
            if (this.options.subtitle != null) {
                this.options.chartConfig.title.subtext = this.options.subtitle;
            }
            if (this.options.legends && $.isArray(this.options.legends)) {
                if (this.options.legends.length > 0) {
                    // 替换新的legend数据
                    this.options.chartConfig.legend.data = this.options.legends;
                }
            }
            //设置直角坐标系的特殊处理
            if (this.options.type == 'line' || this.options.type == 'bar') {
                var datazoom = this.options.chartConfig.dataZoom;
                if (datazoom) {
                    if (datazoom[1] && datazoom[1].show) {
                        //显示dataZoom时,需要空出它的高度,否则会被覆盖
                        this.options.chartConfig.grid.bottom += 40;
                    }
                }
            }
            // 验证是否用户使用额外接口,有的话统一进行覆盖
            if (this.options.config && !$.isEmptyObject(this.options.config)) {
                this.options.chartConfig = $.extend(true, this.options.chartConfig, this.options.config);
            }
        },

        // 根据类型取得图表的默认配置信息
        getDefaultChartConfig: function (type) {
            //加载默认的配置项目
            var config = $.extend(true, {}, defaultSettings);
            //根据类型设置独有的配置项目
            //用户使用不同type类型
            //统一设置各个图形的tooltip函数
            config.tooltip.formatter = this.tooltipFormatter();
            switch (type) {
                case 'line':
                    //设置x、y轴的格式化函数
                    config.xAxis[0].axisLabel.formatter = this.labelFormatter('x');
                    config.yAxis[0].axisLabel.formatter = this.labelFormatter('y');
                    //tooltip
                    break;
                case  'bar':
                    //设置x、y轴的格式化函数
                    config.xAxis[0].axisLabel.formatter = this.labelFormatter('x');
                    config.yAxis[0].axisLabel.formatter = this.labelFormatter('y');
                    //tooltip
                    config.tooltip.axisPointer = {        // 坐标轴指示器，坐标轴触发有效
                        type: 'shadow'                    // 默认为直线，可选为：'line' | 'shadow'
                    };
                    config.xAxis[0].boundaryGap = true;
                    break;
                case  'pie':
                    //饼图需要使用 'vertical'
                    config.legend.orient = 'vertical';
                    //饼图使用right
                    config.legend.left = 'right';
                    //饼图需要考虑工具栏的高度,需要使用 40(数值型)
                    config.legend.top = 40;
                    // 值域范围无效
                    config.dataZoom = null;
                    // 切换图标无效
                    config.toolbox.feature.magicType.show = false;
                    // 横坐标无效
                    config.xAxis = null;
                    // 纵坐标无效
                    config.yAxis = null;
                    // 坐标间距无效
                    config.grid = null;
                    //触发类型，默认数据触发，可选为：'item' | 'axis'
                    config.tooltip.trigger = 'item';
                    break;
                case 'radar':
                    //饼图需要使用 'vertical'
                    config.legend.orient = 'vertical';
                    //饼图使用right
                    config.legend.left = 'right';
                    //饼图需要考虑工具栏的高度,需要使用 40(数值型)
                    config.legend.top = 40;
                    // 值域范围无效
                    config.dataZoom = null;
                    // 切换图标无效
                    config.toolbox.feature.magicType.show = false;
                    // 横坐标无效
                    config.xAxis = null;
                    // 纵坐标无效
                    config.yAxis = null;
                    // 坐标间距无效
                    config.grid = null;
                    //触发类型，默认数据触发
                    config.tooltip.trigger = 'item';
                    //极坐标：雷达图使用,其它设置为空
                    config.radar = [
                        {
                            center: ['50%', '50%'],	  // 圆心坐标，支持绝对值（px）和百分比，百分比计算min(width, height) * 50%
                            radius: '72%',	          // 半径，支持绝对值（px）和百分比，百分比计算min(width, height) / 2 * 75%,
                            scale: false,	          // 脱离0值比例，放大聚焦到最终_min，_max区间
                            precision: 0,             // 小数精度，默认为0，无小数点
                            power: 100,          	  // 整数精度，默认为100，个位和百位为0
                            name: {                   // 坐标轴文本标签选项
                                show: true,
                                // 显示值的格式化
                                formatter: this.labelFormatter()  //格式下坐标的函数
                            },
                            indicator: []	          // 雷达指标列表，同时也是label内容
                        }
                    ]
                    ;
                    break;
                case 'gauge':
                    // legend无效
                    config.legend = null;
                    // 值域范围无效
                    config.dataZoom = null;
                    // 切换图标无效
                    config.toolbox.feature.magicType.show = false;
                    // 横坐标无效
                    config.xAxis = null;
                    // 纵坐标无效
                    config.yAxis = null;
                    // 坐标间距无效
                    config.grid = null;
                    config.tooltip.trigger = 'item';
                    break;
                case 'scatter':
                    //设置x、y轴的格式化函数
                    config.xAxis[0].axisLabel.formatter = this.labelFormatter('x');
                    config.yAxis[0].axisLabel.formatter = this.labelFormatter('y');
                    // 切换图标无效
                    config.toolbox.feature.magicType.show = false;
                    break;
            }

            return config;
        },

        /**
         * 发送请求，取得图表的数据
         * @params options 重新发送请求传递的参数
         */
        request: function (options) {
            var self = this;

            //首先合并更新options
            if (options != null && typeof options == 'object') {
                if (typeof self.options == 'object') {
                    $.extend(true, self.options, options);
                }
            }

            if (this.options.remote == false) {
                self.parseData(self.options);
                return;
            }
            //ajax添加
            var params = $.extend(true, {}, self.options.params);
            //可以自己加入参数，比如分页等
            // console.info(params);

            //发送Ajax请求
            $.ajax({
                url: self.options.dataurl,
                type: 'post',
                //json格式要求严格验证
                dataType: "json",
                data: params,
                success: function (result) {
                    self.options.datas = result;
                    self.parseData(self.options);
                },
                error: function (xhr, error) {
                    console.info('echarts load data error.' + error);
                }
            });
        },

        /**
         * 格式化Ajax请求的数据
         * @param options 所有的配置和数据
         */
        parseData: function (options) {
            var self = this;
            //复制一份结果进行修改，保存原始结果备用
            var datas = $.extend(true, {}, self.options.datas);
            //可以把数据在这里进行转换
            //添加转换好的数据到图
            this.setData(datas);
        },

        //添加转换好格式的数据
        setData: function (datas) {
            //  console.info(datas);
            // console.info(this.options);
            if (this.options.type == 'line') {
                this.__addLineSeries(datas, this.options.stack, this.options.area, this.options.legends);
            } else if (this.options.type == 'bar') {
                this.__addBarSeries(datas, this.options.stack, this.options.legends);
            } else if (this.options.type == 'pie') {
                this.__addPieSeries(datas, this.options.name, this.options.radius);
            } else if (this.options.type == 'radar') {
                this.__addRadarSeries(datas, this.options.name, this.options.radius, this.options.legends);
            } else if (this.options.type == 'gauge') {
                this.__addGaugeSeries(datas, this.options.name);
            } else if (this.options.type == 'scatter') {
                this.__addScatterSeries(datas, this.options.name, this.options.legends);
            }
            //console.info(this.options.chartConfig);
            this.refresh();
        },

        /**
         * 刷新图表
         */
        refresh: function () {
            if (this.options.chart && this.options.chart.dispose) {
                this.options.chart.dispose();
            }
            //使用自定义主题
            this.options.chart = echarts.init(this.options.databind, theme);
            console.info(this.options.title);
            console.info(this.options.chartConfig);
            this.options.chart.setOption(this.options.chartConfig, true);
            window.onresize = this.options.chart.resize;
            //注册用户的双击事件
            var dblclick = this.options.dblclick;
            if (dblclick) {
                if (typeof dblclick == 'function') {
                    this.options.chart.on('dblclick', dblclick);
                }
            }
        },

        /**
         * 获取图表
         * @returns {*} chart对象
         */
        getChart: function () {
            return this.options.chart;
        },

        /**
         * 获取图表选项
         * @returns {*} chart对象选项
         */
        getChartConfig: function () {
            return this.options.chartConfig;
        },

        /**
         * 清除图表
         */
        close: function () {
            this.options.chart.clear();
            this.options.chart.dispose();
        },

        /**
         * 字符串数组,类似['上行流量','下行流量']
         * 线图和柱图、雷达图必须设置
         */
        setLegend: function (legends) {
            if (legends && $.isArray(legends)) {
                if (legends.length > 0) {
                    // 替换新的legend数据
                    this.options.chartConfig.legend.data = this.options.legends;
                    //$.merge(this.options.chartConfig.legend.data, this.options.legends);
                    this.refresh();
                }
            }
        },
        addSeries: function () {
        },

        //data格式 :{xAxis:'一月',series:[1,2,3]}
        addSerie: function (data, grow) {
            // 动态数据接口 addData
            if (data != null) {
                if (this.options.chart) {
                    var oldOption = this.options.chart.getOption();
                }
                if (!grow) {
                    oldOption.xAxis[0].data.shift();
                }
                oldOption.xAxis[0].data.push(data.xAxis); // 坐标轴标签
                for (var i = 0; i < data['series'].length; i++) {

                    var datax = oldOption.series[i].data;
                    if (!grow) {
                        datax.shift(); // 是否增加队列长度，false则自定删除原有数据，队头插入删队尾，队尾插入删队头
                    }
                    datax.push(data['series'][i]); // 新增数据
                }
                if (this.options.chart) {
                    this.options.chart.setOption(oldOption);
                }
            }
        },

        removeSerie: function () {
        },
        removeAllSeries: function () {
        },

        /**
         * 重新设置title
         * @param title
         */
        setTitle: function (title) {
            this.options.chartConfig.title.text = title;
            this.refresh();
        },
        /**
         * 重新设置副title
         * @param subTitle
         */
        setSubTitle: function (subTitle) {
            this.options.chartConfig.title.subtext = subTitle;
            this.refresh();
        },
        /**
         * 设置主题样式
         * 可选主题： macarons、infographic、shine、dark、blue、green、red、gray、default
         */
        setTheme: function (theme) {
        },

        render: function () {
        },

        //tooltip显示格式化
        /**
         * {string}，模板（Template），其变量为：
         * {a} | {a0}
         * {b} | {b0}
         * {c} | {c0}
         * {d} | {d0} （部分图表类型无此项）
         * 多值下则存在多套{a1}, {b1}, {c1}, {d1}, {a2}, {b2}, {c2}, {d2}, ...
         * 其中变量a、b、c、d在不同图表类型下代表数据含义为：
         *      折线（区域）图、柱状（条形）图、K线图 : a（系列名称），b（类目值），c（数值）, d（无）
         *      饼图、雷达图、仪表盘、漏斗图: a（系列名称），b（数据项名称），c（数值）, d（饼图：百分比 | 雷达图：指标名称）
         *  {Function}，传递参数列表如下：
         *      <Object> params :
         *       {
         *            componentType: 'series',
         *            // 系列类型
         *            seriesType: string,
         *            // 系列在传入的 option.series 中的 index
         *            seriesIndex: number,
         *            // 系列名称
         *            seriesName: string,
         *            // 数据名，类目名
         *            name: string,
         *           // 数据在传入的 data 数组中的 index
         *           dataIndex: number,
         *           // 传入的原始数据项
         *           data: Object,
         *           // 传入的数据值
         *           value: number|Array,
         *           // 数据图形的颜色
         *          color: string,
         *           // 饼图的百分比
         *           percent: number,
         *        }
         *      <String> ticket : 异步回调标识
         *      <Function> callback : 异步回调，回调时需要两个参数，第一个为前面提到的ticket，第二个为填充内容html
         */
        tooltipFormatter: function () {
            // 提示显示格式化
            var self = this;
            var tiltediv = '<div style="border-bottom: 1px solid rgba(255,255,255,.3); font-size: 18px;padding-bottom: 7px;margin-bottom: 7px">';
            // 优先使用用户自定义函数
            if (this.options.tooltipFormatter != null) {
                return this.options.tooltipFormatter;
            }
            if (this.options.type == 'gauge') {
                //仪表盘显示格式:'[张三 ：<br/> 完成率 ：35.7%]'
                return "{a} <br/>{b} : {c}%";
            } else if (this.options.type == 'radar') {
                // {a}、{b}、{c}，分别表示系列名，数据名，数据值
                //雷达图显示标签:'[张三：<br/> 流量：1000 <br/> 速率：235]'
                return function (params) {
                    var res = tiltediv + self.options.title + ' : </div>' + params['name'];
                    var ins = self.options.chartConfig.radar[0].indicator;
                    for (var i = 0, l = params['value'].length; i < l; i++) {
                        if (self.options.formatType == 'flow') {
                            res += '<br/>' + ins[i]['text'] + ' : ' + self.flowTransform(params['value'][i]);
                        } else {
                            res += '<br/>' + ins[i]['text'] + ' : ' + self.packetTransform(params['value'][i]);
                        }
                    }
                    return res;
                };
            } else if (this.options.type == 'pie') {
                //饼图显示格式:'[张三 ：<br/> 工作比率 ：1200（35.7%）]'
                return function (params) {
                    var res = tiltediv + self.options.title + ' : </div>';
                    if (self.options.formatType == 'flow') {
                        res += '<br/>' + params['seriesName'] + ' : ' + self.flowTransform(params['value']) + ' (' + params['percent'] + '%)';
                    } else {
                        res += '<br/>' + params['seriesName'] + ' : ' + self.packetTransform(params['value']) + ' (' + params['percent'] + '%)';
                    }
                    return res;
                };
            } else if (this.options.type == 'line' || this.options.type == 'bar') {
                //线图和柱图一起处理
                return function (params) {
                    var res = tiltediv + self.options.title + ' : </div>' + params[0]['name'];
                    for (var i = 0, l = params.length; i < l; i++) {
                        if (self.options.formatType == 'flow') {
                            res += '<br/>' + params[i]['seriesName'] + ' : ' + self.flowTransform(params[i]['value']);
                        } else {
                            res += '<br/>' + params[i]['seriesName'] + ' : ' + self.packetTransform(params[i]['value']);
                        }
                    }
                    return res;
                };
            } else if (this.options.type == 'scatter') {
                // 气泡(散点)图的处理
                return function (params) {

                    var res = tiltediv + self.options.title + ' : </div>' + params[0]['name'];
                    for (var i = 0, l = params.length; i < l; i++) {
                        if (self.options.formatType == 'flow') {
                            res += '<br/>' + params[i]['seriesName'] + ' : ' + self.flowTransform(params[i]['value']);
                        } else {
                            res += '<br/>' + params[i]['seriesName'] + ' : ' + self.packetTransform(params[i]['value']);
                        }
                    }
                    return res;
                };
            }
            return null;
        },

        //label显示格式化
        //TODO 添加格式化函数具体内容
        labelFormatter: function (axis) {
            // console.info(this.options.type);
            var self = this;
            //优先使用用户自定义函数
            if (this.options.labelFormatter != null) {
                return this.options.labelFormatter;
            }
            if (this.options.type == 'gauge') {
                //仪表盘显示格式:'85.25%'
                return function (value) {
                    return value + '%';
                };
            } else if (this.options.type == 'radar') {
                //雷达图显示标签:'[效率]'
                return function (value) {
                    return '[' + value + ']';
                };
            } else if (this.options.type == 'line' || this.options.type == 'bar' || this.options.type == 'scatter') {
                // console.info(axis);
                if (axis == null || (axis != null && axis != 'undefined' && (axis == 'x' || axis == 'xAxis'))) {
                    // xAxis //x //null 表示x坐标轴
                    return function (value) {
                        return value;
                    };
                } else {
                    // y坐标轴
                    return function (value) {
                        if (self.options.formatType == 'flow') {
                            return self.flowTransform(value, 0);
                        } else {
                            return self.packetTransform(value, 0);
                        }
                    };
                }
            }
        },

        /**
         * 转换流量、流量速率、存储、内存大小等以1024为换算的值
         */
        flowTransform: function (val, offset) {

            var fix = 2;
            if (offset != null && fix != 'undefined') {
                fix = offset;
            }

            if (val == 0) {
                return val;
            }
            if (val < 1024) {
                return val + " B";
            } else if (val < 1048576) {
                return (val / 1024).toFixed(fix) + " KB";
            } else if (val < 1073741824) {
                return (val / 1048576).toFixed(fix) + " MB";
            } else {
                return (val / 1073741824).toFixed(fix) + " GB";
            }
        },

        /**
         * 转换报文数、统计数、计算数等以1000为换算的值
         */
        packetTransform: function (val, offset) {

            var fix = 2;
            if (offset != null && fix != 'undefined') {
                fix = offset;
            }

            if (val == 0) {
                return val;
            }
            if (val < 1000) {
                return val + " ";
            } else if (val < 1000000) {
                return (val / 1000).toFixed(fix) + " K";
            } else if (val < 1000000000) {
                return (val / 1000000).toFixed(fix) + " M";
            } else {
                return (val / 1000000000).toFixed(fix) + " G";
            }
        },

        //添加柱图数据
        // {
        //    'xAxis': ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月'],
        //    'series': [
        //        [120, 232, 301, 434, 390, 530, 320, 120, 250],
        //        [150, 160, 190, 150, 232, 201, 154, 390, 110]
        //    ]
        // }
        __addBarSeries: function (datas, stack, legends) {
            //var series = $.extend(true, [], chartConfig.series);
            //清空数据，防止刷新污染
            this.options.chartConfig.series = [];
            var series = this.options.chartConfig.series;
            var xAxis = this.options.chartConfig.xAxis;
            var yAxis = this.options.chartConfig.yAxis;

            if ($.isArray(legends) && legends.length > 0) {
                $.each(legends, function (index, item) {
                    var serie = {};
                    if (stack) {
                        serie.stack = '总量';
                        yAxis[0].scale = false;
                    }
                    serie.type = 'bar';
                    serie.name = item;
                    serie.barMaxWidth = 36;
                    // 图形样式，可设置图表内图形的默认样式和强调样式
                    serie.itemStyle = {
                        normal: {},
                        emphasis: {}
                    };
                    serie.data = [];
                    if (datas != null && datas != undefined) {
                        if (datas['xAxis'] == null || datas['xAxis'].length == 0) {
                            xAxis[0].data = [''];
                        } else {
                            xAxis[0].data = datas['xAxis'];
                        }
                        if (datas['series'] == null || datas['series'][index].length == 0) {
                            serie.data = [0];
                        } else {
                            serie.data = datas['series'][index];
                        }
                    }
                    series.push(serie);
                });
            }
        },
        //添加线图数据
        // {
        //    'xAxis': ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月'],
        //    'series': [
        //        [120, 232, 301, 434, 390, 530, 320, 120, 250],
        //        [150, 160, 190, 150, 232, 201, 154, 390, 110]
        //    ]
        // }
        __addLineSeries: function (datas, stack, area, legends) {
            // var series = $.extend(true, [], defaultSettings.series);
            //清空数据，防止刷新污染
            this.options.chartConfig.series = [];
            var series = this.options.chartConfig.series;
            var xAxis = this.options.chartConfig.xAxis;
            var yAxis = this.options.chartConfig.yAxis;

            //取得设置的symbol属性
            var symbol = this.options.chartConfig.symbol;
            if (typeof(symbol) == 'undefined') {
                symbol = 'circle';
            }
            if ($.isArray(legends) && legends.length > 0) {
                $.each(legends, function (index, item) {
                    var serie = {};
                    if (stack) {
                        serie.stack = '总量';
                        yAxis[0].scale = false;
                    }
                    serie.type = 'line';
                    serie.name = item;
                    serie.smooth = true;
                    serie.symbol = symbol;
                    // 图形样式，可设置图表内图形的默认样式和强调样式
                    if (area) {
                        serie.itemStyle = {
                            normal: {areaStyle: {type: 'default'}},
                            emphasis: {}
                        };
                    }

                    serie.data = [];
                    if (datas != null && datas != undefined) {
                        if (datas['xAxis'] == null || datas['xAxis'].length == 0) {
                            xAxis[0].data = [''];
                        } else {
                            xAxis[0].data = datas['xAxis'];
                        }
                        if (datas['series'] == null || datas['series'][index].length == 0) {
                            serie.data = [0];
                        } else {
                            serie.data = datas['series'][index];
                        }
                    }
                    series.push(serie);
                });
            }
        },
        //对于pie图来说,每个项目只有一个值,但是为了接口统一,我们把值也放入数组中
        // {
        //      'xAxis': ['张三', '李四', '王五', '赵六', '小明'],
        //      'series': [
        //          [120, 232, 301, 434, 390]
        //       ]
        // }
        __addPieSeries: function (datas, name, radius) {
            // var series = $.extend(true, [], defaultSettings.series);
            //清空数据，防止刷新污染
            this.options.chartConfig.series = [];
            var series = this.options.chartConfig.series;
            if (datas != null) {
                var serie = {};
                serie.type = 'pie';
                serie.name = name;
                serie.center = ['50%', '54%'];
                //半径，支持绝对值（px）和百分比，百分比计算比，min(width, height) / 2 * 75%， 传数组实现环形图，[内半径，外半径]
                if (radius) {
                    serie.radius = ['50%', '72%'];
                    // 图形样式，可设置图表内图形的默认样式和强调样式
                    serie.itemStyle = {
                        normal: {
                            label: {
                                show: false
                            },
                            labelLine: {
                                show: false
                            }
                        },
                        emphasis: {
                            label: {
                                show: true,
                                position: 'center',
                                textStyle: {
                                    fontSize: '30',
                                    fontWeight: 'bold'
                                }
                            }
                        }
                    }
                } else {
                    serie.radius = '72%';
                }
                serie.data = [];
                this.options.chartConfig.legend.data = datas['xAxis'];

                if (datas['series'] != null) {
                    $.each(datas['series'][0], function (index, item) {
                        serie.data.push({name: datas['xAxis'][index], value: item});
                    });
                }
                series.push(serie);
            }
        },
        //对于radar图来说,每个项目的值要和indicator对应
        // {
        //    'xAxis': ['流量', '报文', '速率', '攻击', '病毒'],
        //    'max': [1000, 1500, 100, 300, 200],
        //    'series': [
        //        [820, 1232, 31, 241, 100],
        //        [320, 800, 91, 234, 10]
        //     ]
        // }
        //indicator 也需要动态[{text:'角度',max:1000},{{text:'方法',max:2000}]
        __addRadarSeries: function (datas, name, radius, legends) {
            //  var series = $.extend(true, [], defaultSettings.series);
            //清空数据，防止刷新污染
            this.options.chartConfig.series = [];
            var series = this.options.chartConfig.series;
            var radar = this.options.chartConfig.radar;
            if (datas != null) {
                $.each(datas['xAxis'], function (index, item) {
                    radar[0].indicator.push({text: item, max: datas['max'][index]});
                });

                var serie = {};
                serie.type = 'radar';
                serie.name = name;
                if (radius) {
                    // 图形样式，可设置图表内图形的默认样式和强调样式
                    serie.itemStyle = {
                        normal: {
                            areaStyle: {
                                type: 'default'
                            }
                        }
                    }
                }
                serie.data = [];
                $.each(datas['series'], function (index, item) {
                    //console.info(legends);
                    serie.data.push({name: legends[index], value: item});
                });
                series.push(serie);
            }
        },
        //gauge,每个图只有一个显示值，需要一个最大值和一个最小值
        //    {
        //        "xAxis": ["速率"],
        //        "min": [0],
        //        "max": [200],
        //        "series": [
        //        [120]
        //        ]
        //    }
        //min 和 max 是否动态 需要考虑.
        __addGaugeSeries: function (datas, name) {
            //取得series
            //清空数据，防止刷新污染
            this.options.chartConfig.series = [];
            var series = this.options.chartConfig.series;
            if (datas != null) {
                var serie = {};
                serie.type = 'gauge';
                serie.name = name;
                // 圆心坐标，支持绝对值（px）和百分比，百分比计算min(width, height) * 50%
                serie.center = ['50%', '54%'];
                // 分割段数，默认为5，为0时为线性渐变，calculable为true是默认均分100份
                serie.splitNumber = 10;
                //半径，支持绝对值（px）和百分比，百分比计算比，min(width, height) / 2 * 75%， 传数组实现环形图，[内半径，外半径]
                serie.radius =  '75%';
                // 坐标轴线，默认显示
                serie.axisLine = {            // 坐标轴线
                    lineStyle: {       // 属性lineStyle控制线条样式
                        color: [
                            [0.2, '#228b22'],
                            [0.8, '#48b'],
                            [1, '#ff4500']
                        ],
                        width: 8
                    }
                };
                serie.title = {
                    show: true,
                    offsetCenter: [0, '-40%'],       // x, y，单位px
                    textStyle: {       // 其余属性默认使用全局文本样式，详见TEXTSTYLE
                        fontWeight: 'bolder'
                    }
                };
                serie.detail = {
                    // 显示值的格式化
                    formatter: this.labelFormatter(),
                    textStyle: {       // 其余属性默认使用全局文本样式，详见TEXTSTYLE
                        color: 'auto',
                        fontWeight: 'bolder'
                    }
                };
                //设置最小刻度
                if (datas['min'] != null && datas['min'].length > 0) {
                    serie.min = datas['min'][0];
                } else {
                    serie.min = 0;
                }
                //设置最大刻度
                if (datas['max'] != null && datas['max'].length > 0) {
                    serie.max = datas['max'][0];
                } else {
                    serie.max = 100;
                }
                serie.data = [];
                if (datas['xAxis'] != null && datas['xAxis'].length > 0 && datas['series'] != null && datas['series'].length > 0) {
                    serie.data.push({name: datas['xAxis'][0], value: datas['series'][0][0]});
                }
                series.push(serie);
            }
        },
        //添加线图数据
        // {
        //    'xAxis': ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月'],
        //    'series': [
        //        [120, 232, 301, 434, 390, 530, 320, 120, 250],
        //        [150, 160, 190, 150, 232, 201, 154, 390, 110]
        //    ]
        // }
        __addScatterSeries: function (datas, name, legends) {
            // var series = $.extend(true, [], defaultSettings.series);
            //清空数据，防止刷新污染
            this.options.chartConfig.series = [];
            var series = this.options.chartConfig.series;
            var xAxis = this.options.chartConfig.xAxis;
            var yAxis = this.options.chartConfig.yAxis;

            // 设置style
            var itemStyle = {
                normal: {
                    opacity: 0.8,
                    shadowBlur: 10,
                    shadowOffsetX: 0,
                    shadowOffsetY: 0,
                    shadowColor: 'rgba(0, 0, 0, 0.5)'
                }
            };
            if ($.isArray(legends) && legends.length > 0) {
                $.each(legends, function (index, item) {
                    var serie = {};
                    serie.type = 'scatter';
                    serie.name = item;
                    // 图形样式，可设置图表内图形的默认样式和强调样式
                    serie.itemStyle = itemStyle;
                    serie.symbolSize = function (data) {
                        return 25;
                    };
                    serie.data = [];
                    if (datas != null && datas != undefined) {
                        if (datas['xAxis'] == null || datas['xAxis'].length == 0) {
                            xAxis[0].data = [''];
                        } else {
                            xAxis[0].data = datas['xAxis'];
                        }
                        if (datas['series'] == null || datas['series'][index].length == 0) {
                            serie.data = [0];
                        } else {
                            serie.data = datas['series'][index];
                        }
                    }
                    series.push(serie);
                });
            }
        }
    };

    return ChartData;
}))
;
